#include "Vec3.h"
#include "MathBase.h"

SVec3 SVec3::SafeDivide(const SVec3 &Other, double Error) const
{
	return SVec3(
		CMathBase::SafeDivide(X,Other.X,Error),
		CMathBase::SafeDivide(Y,Other.Y,Error),
		CMathBase::SafeDivide(Z,Other.Z,Error)
	);
}

SVec3 &SVec3::SafeDivideSelf(const SVec3 &Other, double Error)
{
	X=CMathBase::SafeDivide(X,Other.X,Error);
	Y=CMathBase::SafeDivide(Y,Other.Y,Error);
	Z=CMathBase::SafeDivide(Z,Other.Z,Error);
	return *this;
}

SVec3 SVec3::SafeDivide(const SVec3 &A, const SVec3 &B, double Error)
{
	return SVec3(
		CMathBase::SafeDivide(A.X,B.X,Error),
		CMathBase::SafeDivide(A.Y,B.Y,Error),
		CMathBase::SafeDivide(A.Z,B.Z,Error)
	);
}

SVec3 SVec3::SafeDivide(Float Other ,double Error) const
{
	return SVec3(
		CMathBase::SafeDivide(X,Other,Error),
		CMathBase::SafeDivide(Y,Other,Error),
		CMathBase::SafeDivide(Z,Other,Error)
	);
}

SVec3 &SVec3::SafeDivideSelf(Float Other,double Error)
{
	X=CMathBase::SafeDivide(X,Other,Error);
	Y=CMathBase::SafeDivide(Y,Other,Error);
	Z=CMathBase::SafeDivide(Z,Other,Error);
	return *this;
}

SVec3 SVec3::SafeDivide(const SVec3 &A, Float B, double Error)
{
	return SVec3(
		CMathBase::SafeDivide(A.X,B,Error),
		CMathBase::SafeDivide(A.Y,B,Error),
		CMathBase::SafeDivide(A.Z,B,Error)
	);
}

void SVec3::Initialize(Float InX, Float InY, Float InZ)
{
	X = InX;
	Y = InY;
	Z = InZ;
}

Float SVec3::GetLength()
{
	return CMathBase::Sqrt(X * X + Y * Y + Z * Z);
}

Float SVec3::GetLengthSquared()
{
	return X * X + Y * Y + Z * Z;
}

Float SVec3::GetMax() const
{
	return X > Y ? (X > Z ? X : Z) : (Y > Z ? Y : Z);
}

void SVec3::Normalize()
{
	Float InvLength = CMathBase::InvSqrt(X * X + Y * Y + Z * Z);
	X *= InvLength;
	Y *= InvLength;
	Z *= InvLength;
}

SVec3 SVec3::ToNormalized() const
{
	SVec3 New = *this;
	New.Normalize();
	return New;
}

SVec3 operator*(const Float& Other, const SVec3& InVector)
{
	return InVector* Other;
}

CString SVec3::ToString() const
{
	return U"Vec3(X:"+CString(X)
            +U",Y:"+CString(Y)
            +U",Z:"+CString(Z)
            +U")";	

}

void SVec3::ToFloatArray(float OutArray[3]) const
{
	OutArray[0] = X;
	OutArray[1] = Y;
	OutArray[2] = Z;
}

CString WH::ToString(const SVec3 &InValue)
{
	return InValue.ToString();
}
